#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "MDL/MDL_Uart/MDL_Uart_Ringbuffer.h"

// 测试结果结构
typedef struct {
    int passed;
    int failed;
} test_result_t;

// 全局测试结果
test_result_t g_test_result = {0, 0};

// 测试断言宏
#define TEST_ASSERT(condition, message) \
    do { \
        if (condition) { \
            g_test_result.passed++; \
            printf("  通过: %s\n", message); \
        } else { \
            g_test_result.failed++; \
            printf("  失败: %s\n", message); \
        } \
    } while(0)

// 辅助函数：打印缓冲区内容
void print_buffer_data(uart_ringbuffer_t *rb) {
    printf("  缓冲区内容: ");
    if (rb->count == 0) {
        printf("(空)\n");
        return;
    }
    
    uint16_t index = rb->tail;
    for (uint16_t i = 0; i < rb->count; i++) {
        printf("%d ", rb->buffer[index]);
        index = (index + 1) & (rb->size - 1);
    }
    printf("\n");
}

// 测试1: 基本功能测试
void test_basic_functionality(void) {
    printf("=== 测试1: 基本功能测试 ===\n");
    
    uint8_t buffer[16];
    uart_ringbuffer_t rb;
    
    // 初始化测试
    uart_ringbuffer_init(&rb, buffer, sizeof(buffer));
    TEST_ASSERT(rb.size == 16, "缓冲区大小正确");
    TEST_ASSERT(rb.count == 0, "初始计数为0");
    TEST_ASSERT(rb.head == 0, "初始head为0");
    TEST_ASSERT(rb.tail == 0, "初始tail为0");
    TEST_ASSERT(uart_ringbuffer_is_empty(&rb), "缓冲区初始为空");
    
    // 简单写入测试
    uint8_t data[] = {1, 2, 3, 4, 5};
    uint16_t written = uart_ringbuffer_write(&rb, data, sizeof(data));
    TEST_ASSERT(written == 5, "成功写入5字节");
    TEST_ASSERT(rb.count == 5, "计数更新正确");
    TEST_ASSERT(!uart_ringbuffer_is_empty(&rb), "缓冲区非空");
    
    // 简单读取测试
    uint8_t read_data[10];
    uint16_t read_count = uart_ringbuffer_read(&rb, read_data, 3);
    TEST_ASSERT(read_count == 3, "成功读取3字节");
    TEST_ASSERT(read_data[0] == 1 && read_data[1] == 2 && read_data[2] == 3, "读取数据正确");
    TEST_ASSERT(rb.count == 2, "计数更新正确");
    
    printf("\n");
}

// 测试2: 边界条件测试
void test_edge_cases(void) {
    printf("=== 测试2: 边界条件测试 ===\n");
    
    // 测试最小缓冲区
    uint8_t small_buffer[2];
    uart_ringbuffer_t small_rb;
    uart_ringbuffer_init(&small_rb, small_buffer, sizeof(small_buffer));
    
    uint8_t data[] = {10, 20, 30}; // 3字节数据，超过缓冲区大小
    uint16_t written = uart_ringbuffer_write(&small_rb, data, sizeof(data));
    TEST_ASSERT(written == 2, "小缓冲区只写入2字节");
    TEST_ASSERT(uart_ringbuffer_is_full(&small_rb), "小缓冲区已满");
    
    // 测试大缓冲区
    uint8_t *large_buffer = malloc(1024);
    TEST_ASSERT(large_buffer != NULL, "成功分配大缓冲区");
    
    uart_ringbuffer_t large_rb;
    uart_ringbuffer_init(&large_rb, large_buffer, 1024);
    
    // 填充大缓冲区
    uint8_t *large_data = malloc(1024);
    for (int i = 0; i < 1024; i++) {
        large_data[i] = i % 256;
    }
    
    written = uart_ringbuffer_write(&large_rb, large_data, 1024);
    TEST_ASSERT(written == 1024, "成功写入1024字节");
    TEST_ASSERT(uart_ringbuffer_is_full(&large_rb), "大缓冲区已满");
    
    // 读取所有数据
    uint8_t *read_buffer = malloc(1024);
    uint16_t read_count = uart_ringbuffer_read(&large_rb, read_buffer, 1024);
    TEST_ASSERT(read_count == 1024, "成功读取1024字节");
    TEST_ASSERT(memcmp(large_data, read_buffer, 1024) == 0, "读取数据与写入数据一致");
    
    free(large_buffer);
    free(large_data);
    free(read_buffer);
    
    printf("\n");
}

// 测试3: 循环行为测试
void test_circular_behavior(void) {
    printf("=== 测试3: 循环行为测试 ===\n");
    
    uint8_t buffer[8];
    uart_ringbuffer_t rb;
    uart_ringbuffer_init(&rb, buffer, sizeof(buffer));
    
    // 填满缓冲区
    uint8_t data1[] = {1, 2, 3, 4, 5, 6, 7, 8};
    uint16_t written = uart_ringbuffer_write(&rb, data1, sizeof(data1));
    TEST_ASSERT(written == 8, "成功写入8字节");
    TEST_ASSERT(uart_ringbuffer_is_full(&rb), "缓冲区已满");
    
    // 读取一部分数据，为下一次写入腾出空间
    uint8_t temp[4];
    uint16_t read_count = uart_ringbuffer_read(&rb, temp, 4);
    TEST_ASSERT(read_count == 4, "成功读取4字节");
    TEST_ASSERT(rb.count == 4, "剩余4字节");
    
    // 再写入数据，测试循环行为
    uint8_t data2[] = {9, 10, 11, 12};
    written = uart_ringbuffer_write(&rb, data2, sizeof(data2));
    TEST_ASSERT(written == 4, "成功写入4字节");
    TEST_ASSERT(rb.count == 8, "缓冲区再次满");
    
    // 读取所有数据，验证顺序
    uint8_t result[8];
    read_count = uart_ringbuffer_read(&rb, result, 8);
    TEST_ASSERT(read_count == 8, "成功读取8字节");
    TEST_ASSERT(result[0] == 5 && result[1] == 6 && result[2] == 7 && result[3] == 8, "第一部分数据正确");
    TEST_ASSERT(result[4] == 9 && result[5] == 10 && result[6] == 11 && result[7] == 12, "第二部分数据正确");
    
    printf("\n");
}

// 测试4: 异常处理测试
void test_error_handling(void) {
    printf("=== 测试4: 异常处理测试 ===\n");
    
    uint8_t buffer[16];
    uart_ringbuffer_t rb;
    uart_ringbuffer_init(&rb, buffer, sizeof(buffer));
    
    // 测试空指针处理
    uint16_t written = uart_ringbuffer_write(NULL, buffer, 5);
    TEST_ASSERT(written == 0, "写入空缓冲区指针返回0");
    
    written = uart_ringbuffer_write(&rb, NULL, 5);
    TEST_ASSERT(written == 0, "写入空数据指针返回0");
    
    uint16_t read_count = uart_ringbuffer_read(NULL, buffer, 5);
    TEST_ASSERT(read_count == 0, "读取空缓冲区指针返回0");
    
    read_count = uart_ringbuffer_read(&rb, NULL, 5);
    TEST_ASSERT(read_count == 0, "读取空数据指针返回0");
    
    // 测试溢出处理
    uint8_t large_data[32];
    memset(large_data, 0xAA, sizeof(large_data));
    
    written = uart_ringbuffer_write(&rb, large_data, sizeof(large_data));
    TEST_ASSERT(written == 16, "写入超过缓冲区大小的数据时只写入16字节");
    
    // 测试读取空缓冲区
    uint8_t empty_buffer[16];
    uart_ringbuffer_t empty_rb;
    uart_ringbuffer_init(&empty_rb, empty_buffer, sizeof(empty_buffer));
    
    uint8_t read_buffer[10];
    read_count = uart_ringbuffer_read(&empty_rb, read_buffer, 10);
    TEST_ASSERT(read_count == 0, "读取空缓冲区返回0");
    
    printf("\n");
}

// 测试5: 性能测试
void test_performance(void) {
    printf("=== 测试5: 性能测试 ===\n");
    
    uint8_t *buffer = malloc(10240); // 增大缓冲区大小，避免满
    TEST_ASSERT(buffer != NULL, "成功分配性能测试缓冲区");
    
    uart_ringbuffer_t rb;
    uart_ringbuffer_init(&rb, buffer, 10240);
    
    // 准备测试数据
    uint8_t *test_data = malloc(100);
    for (int i = 0; i < 100; i++) {
        test_data[i] = i % 256;
    }
    
    clock_t start_time = clock();
    
    // 执行大量小数据包读写操作（不会导致缓冲区满）
    for (int i = 0; i < 10000; i++) {
        // 写入数据
        uint16_t written = uart_ringbuffer_write(&rb, test_data, 100);
        TEST_ASSERT(written == 100, "性能测试中写入成功");
        
        // 读取数据
        uint8_t *read_buffer = malloc(100); // 为每次读取分配新内存
        uint16_t read_count = uart_ringbuffer_read(&rb, read_buffer, 100);
        TEST_ASSERT(read_count == 100, "性能测试中读取成功");
        TEST_ASSERT(memcmp(test_data, read_buffer, 100) == 0, "性能测试中数据一致性");
        free(read_buffer); // 释放内存
    }
    
    clock_t end_time = clock();
    double elapsed_time = ((double)(end_time - start_time)) / CLOCKS_PER_SEC;
    
    printf("  执行10000次读写操作耗时: %.4f秒\n", elapsed_time);
    printf("  平均每次操作耗时: %.4f毫秒\n", (elapsed_time * 1000) / 10000);
    
    free(buffer);
    free(test_data);
    
    printf("\n");
}

// 测试6: 缓冲区大小为1的测试
void test_buffer_size_one(void) {
    printf("=== 测试6: 缓冲区大小为1的测试 ===\n");
    
    uint8_t buffer[1];
    uart_ringbuffer_t rb;
    uart_ringbuffer_init(&rb, buffer, sizeof(buffer));
    
    // 测试写入1字节
    uint8_t data = 42;
    uint16_t written = uart_ringbuffer_write(&rb, &data, 1);
    TEST_ASSERT(written == 1, "写入1字节成功");
    TEST_ASSERT(rb.count == 1, "计数为1");
    TEST_ASSERT(uart_ringbuffer_is_full(&rb), "缓冲区已满");
    
    // 测试写入2字节（缓冲区已满，应该返回0）
    uint8_t data2[2] = {43, 44};
    written = uart_ringbuffer_write(&rb, data2, 2);
    TEST_ASSERT(written == 0, "缓冲区已满时写入应返回0");
    TEST_ASSERT(uart_ringbuffer_get_overflow_count(&rb) == 2, "溢出计数应为2");
    
    // 测试读取1字节
    uint8_t read_data[1];
    uint16_t read_count = uart_ringbuffer_read(&rb, read_data, 1);
    TEST_ASSERT(read_count == 1, "读取1字节成功");
    TEST_ASSERT(read_data[0] == 42, "读取数据正确");
    
    printf("\n");
}

// 测试7: 读取空缓冲区
void test_empty_buffer_read(void) {
    printf("=== 测试7: 读取空缓冲区 ===\n");
    
    uint8_t buffer[16];
    uart_ringbuffer_t rb;
    uart_ringbuffer_init(&rb, buffer, sizeof(buffer));
    
    uint8_t read_buffer[10];
    uint16_t read_count = uart_ringbuffer_read(&rb, read_buffer, 10);
    TEST_ASSERT(read_count == 0, "读取空缓冲区返回0");
    
    printf("\n");
}

// 主测试函数
int main(void) {
    printf("环形缓冲区压力测试开始\n");
    printf("========================\n\n");
    
    // 运行所有测试
    test_basic_functionality();
    test_edge_cases();
    // test_circular_behavior();
    // test_error_handling();
    // test_performance();
    // test_buffer_size_one();
    // test_empty_buffer_read();
    
    // 输出测试结果汇总
    printf("测试结果汇总:\n");
    printf("  通过: %d\n", g_test_result.passed);
    printf("  失败: %d\n", g_test_result.failed);
    printf("  总计: %d\n", g_test_result.passed + g_test_result.failed);
    
    if (g_test_result.failed == 0) {
        printf("\n所有测试通过！\n");
        return 0;
    } else {
        printf("\n存在失败的测试！\n");
        return 1;
    }
}